package com.example.service.impl;

import com.example.service.OnlineUserTrackerService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.time.Duration;

public class OnlineUserTrackerServiceImpl implements OnlineUserTrackerService {

    private static final String KEY_ONLINE_SET = "online:users"; // 使用Set存储用户ID
    private static final String KEY_USER_HEARTBEAT_PREFIX = "online:user:"; // 每个用户一个心跳Key

    private final StringRedisTemplate redisTemplate;
    private final long ttlSeconds;

    public OnlineUserTrackerServiceImpl(StringRedisTemplate redisTemplate, long ttlSeconds) {
        this.redisTemplate = redisTemplate;
        this.ttlSeconds = ttlSeconds;
    }

    @Override
    public long onLogin(Long userId, String username) {
        if (userId == null) return getOnlineCount();
        String userKey = KEY_USER_HEARTBEAT_PREFIX + userId;
        redisTemplate.opsForValue().set(userKey, StringUtils.hasText(username) ? username : "", Duration.ofSeconds(ttlSeconds));
        redisTemplate.opsForSet().add(KEY_ONLINE_SET, String.valueOf(userId));
        Long size = redisTemplate.opsForSet().size(KEY_ONLINE_SET);
        return size == null ? 0 : size;
    }

    @Override
    public long onLogout(Long userId, String username) {
        if (userId == null) return getOnlineCount();
        String userKey = KEY_USER_HEARTBEAT_PREFIX + userId;
        redisTemplate.delete(userKey);
        redisTemplate.opsForSet().remove(KEY_ONLINE_SET, String.valueOf(userId));
        Long size = redisTemplate.opsForSet().size(KEY_ONLINE_SET);
        return size == null ? 0 : size;
    }

    @Override
    public void refreshOnline(Long userId, String username) {
        if (userId == null) return;
        String userKey = KEY_USER_HEARTBEAT_PREFIX + userId;
        Boolean exists = redisTemplate.hasKey(userKey);
        if (Boolean.TRUE.equals(exists)) {
            redisTemplate.expire(userKey, Duration.ofSeconds(ttlSeconds));
        } else {
            // 兜底：如果key丢了，重新加入
            redisTemplate.opsForValue().set(userKey, StringUtils.hasText(username) ? username : "", Duration.ofSeconds(ttlSeconds));
            redisTemplate.opsForSet().add(KEY_ONLINE_SET, String.valueOf(userId));
        }
    }

    @Override
    public long getOnlineCount() {
        Long size = redisTemplate.opsForSet().size(KEY_ONLINE_SET);
        return size == null ? 0 : size;
    }
}


